home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint110s.zoo
/
syscall.spp
< prev
next >
Wrap
Text File
|
1994-02-11
|
14KB
|
477 lines
; Copyright 1992 Eric R. Smith
; Copyright 1992,1993 Atari Corporation
; All rights reserved.
%include "magic.i"
;
; syscall: interface for system calls. The following entry points are
; defined:
; _mint_bios: entry point for the BIOS calls (trap #13)
; _mint_xbios: entry point for XBIOS calls (trap #14)
; _mint_dos: entry point for GEMDOS calls (trap #1)
; _sig_return: user signal handlers return to this routine (see signal.c)
; it is responsible for restoring the kernel's old context
; via the Psigreturn() system call
; _lineA0: calls the line A initialize routine
; _call_aes: calls the GEM AES
; _call_dosound: calls the XBIOS Dosound() function
; _do_usrcall: calls a user supplied function (e.g. for Supexec), with
; arguments supplied from global variables usrarg1, usrarg2, etc.
; _callout: calls an external function, after first saving all registers,
; and restores the registers afterward
;
; external variables referenced:
; _bios_tab, _bios_max:
; table of entry points for BIOS routines, max # of routine
; _xbios_tab, _xbios_max:
; ditto for XBIOS
; _dos_tab, _dos_max:
; ditto for GEMDOS
; _curproc:
; pointer to current process table entry, and hence to save area for
; context (this is always the first entry in the PROC table).
; _valid_return:
; used to indicate to the kernel that a valid return from user mode
; is taking place
;
; _bconbuf, _bconbsiz, _bconbdev:
; 256 byte buffer for Bconout() output. If _bconbsiz is non-zero,
; there are that many bytes in _bconbuf waiting to be flushed. The
; output is for device _bconbdev.
;
; The C function enter_kernel() is called on entry to the kernel, and the
; function leave_kernel() is called on exit. These functions are responsible
; for saving and restoring the various trap vectors, so that MiNT can trap
; out to TOS directly, but programs can only trap to MiNT.
;
; we also call certain BIOS functions directly if these are known not to
; require saving/restoring of context
;
TEXT
XDEF _mint_bios,_mint_xbios
XDEF _mint_dos
XREF _build_context
XREF _restore_context
XREF _proc_clock ; controls process' allocation of CPU time
XREF _enter_kernel
XREF _leave_kernel
XREF _preempt
XREF _curproc
XREF _bios_tab,_bios_max
XREF _xbios_tab,_xbios_max,_old_xbios
XREF _dos_tab,_dos_max
XREF _bconbuf,_bconbsiz,_bconbdev
XREF _bflush
XREF _ubconstat,_do_bconin,_ubcostat,_kbshift
_mint_dos:
clr.w -(sp) ; no frame format needed
; NOTE: FOR NOW, WE PRESERVE A0 ACROSS GEMDOS CALLS. THIS WILL CHANGE
; SOMEDAY, DON'T RELY ON IT!!!
move.l _curproc,d0 ; note: preserve all regs but d0
addq.l #4,d0 ; for compatibility
move.l d0,-(sp) ; push pointer to syscall context save
jsr _build_context
lea _dos_tab,a5 ; set syscall_tab
move.w _dos_max,d5 ; set syscall_max
;
; copy parameters onto process stack. a0 and a1 were set by _build_context
;
move.l _curproc,a0
move.l (a0),sp ; this puts us in our private stack
move.l 24(a1),-(sp) ; a1 was set by build_context
move.l 20(a1),-(sp)
move.l 16(a1),-(sp)
move.l 12(a1),-(sp)
move.l 8(a1),-(sp)
move.l 4(a1),-(sp)
move.l (a1),-(sp)
move.w #1,-(sp) ; flag for in GEMDOS
jsr _enter_kernel ; set up vectors appropriately
addq.w #2,sp
bra _syscall
_mint_xbios:
;
; Kludge for Setscreen: under Falcon TOS, this
; calls a GEMDOS function (Srealloc) and so
; we must *not* change any of the vectors!!
btst #5,(sp) ; test for user/super mode
beq.s LX_usr
%ifdef ONLY030
lea 8(sp),a1
%else
lea 6(sp),a1 ; supervisor mode: args on stack
tst.w ($59e).w ; test longframe
beq.s LX_check
addq.w #2,a1 ; stack is a bit bigger
%endif
bra.s LX_check
LX_usr:
move.l usp,a1 ; user mode: args on user stack
LX_check:
cmp.w #5,(a1) ; check for Setscreen command
beq.s LX_screen ; no -- fall through
clr.w -(sp) ; no frame format needed
move.l _curproc,a0
pea 4(a0) ; push pointer to syscall context save
jsr _build_context
lea _xbios_tab,a5 ; set syscall_tab
move.w _xbios_max,d5 ; set syscall_max
;
; copy parameters onto process stack. a0 and a1 were set by _build_context
;
move.l _curproc,a0
move.l (a0),sp ; this puts us in our private stack
move.l 24(a1),-(sp) ; a1 was set by build_context
move.l 20(a1),-(sp)
move.l 16(a1),-(sp)
move.l 12(a1),-(sp)
move.l 8(a1),-(sp)
move.l 4(a1),-(sp)
move.l (a1),-(sp)
move.w #0,-(sp) ; flag: NOT GEMDOS
jsr _enter_kernel ; set up vectors appropriately
addq.w #2,sp
bra _syscall
;
; For setscreen, jump directly to the ROM vector --
; this avoids all hazards (like changing the vectors)
LX_screen:
move.l _old_xbios+8,a0
jmp (a0)
_mint_bios:
;
; Entering the kernel can be very expensive; so, we take a short-cut
; if possible -- we try some BIOS functions out, and if they
; succeed without blocking then we're done; otherwise, we go
; through the long procedure for entering the kernel
;
; These shortcuts aren't done when we're called in supervisor mode,
; because TOS uses very tiny stacks (smaller than we want); the
; shortcuts operate on the user-supplied ssp, whereas the "full"
; BIOS code works on our (private) system stack
;
; the shortcuts are also turned off if BIOSBUF=n
;
move.w #0,-(sp) ; flag: NOT a GEMDOS call
jsr _enter_kernel ; set up BIOS vectors
addq.w #2,sp
tst.w _bconbdev ; is BIOS buffering on?
bmi L_bios ; no; skip all this
btst #5,(sp) ; test for user/super mode
bne.s L_bios ; if super, goto L_bios
tst.w _proc_clock ; are we about to be preempted?
beq.s L_bios
move.l usp,a1 ; user mode: args on user stack
L_ubios:
move.w (a1),d0 ; get command
cmp.w #3,d0 ; Bconout?
beq do_bconout ; yes -- go do it
;
; most of the remaining functions require BIOS vectors to be properly
; set up
tst.w _bconbsiz ; is BIOS output waiting?
bne.s L_bios ; yes -- do regular code
; test for various BIOS functions
cmp.w #1,d0 ; Bconstat?
bne.s L_00
move.w 2(a1),-(sp) ; push arg
jsr _ubconstat
L_1out:
addq.l #2,sp
L_0out:
move.l d0,-(sp) ; save d0
ori.w #$0700,sr ; spl7()
jsr _leave_kernel
move.l (sp)+,d0 ; retrieve value to be returned
rte ; return to user
L_00:
cmp.w #2,d0 ; Bconin?
bne.s L_01
move.w 2(a1),-(sp) ; yes; push argument
jsr _do_bconin
addq.w #2,sp
cmp.w #$dead,d0 ; would Bconin block?
bne.s L_0out ; no -- we're done
bra.s L_bios ; yes -- do the long stuff
L_01:
cmp.w #8,d0 ; Bcostat?
bne.s L_02
move.w 2(a1),-(sp) ; push device
jsr _ubcostat ; get status
bra.s L_1out
L_02:
cmp.w #11,d0 ; Kbshift?
bne.s L_bios
move.w 2(a1),-(sp) ; push arg
jsr _kbshift
bra.s L_1out
L_bios:
clr.w -(sp) ; no frame format needed
move.l _curproc,a0
pea 4(a0) ; push pointer to syscall context save
jsr _build_context
lea _bios_tab,a5 ; set syscall_tab
move.w _bios_max,d5 ; set syscall_max
;
; copy parameters onto process stack. a0 and a1 were set by _build_context
;
move.l _curproc,a0
move.l (a0),sp ; this puts us in our private stack
move.l 24(a1),-(sp) ; a1 was set by build_context
move.l 20(a1),-(sp)
move.l 16(a1),-(sp)
move.l 12(a1),-(sp)
move.l 8(a1),-(sp)
move.l 4(a1),-(sp)
move.l (a1),-(sp)
_syscall:
;
; check here to see if we need to flush the Bconout() buffer
;
tst.w _bconbsiz ; characters in buffer?
beq.s L_noflush ; no: OK to proceed
;
; watch out, this could cause a context switch
;
jsr _bflush ; flush the buffer
L_noflush:
;
; figure out which routine to call
;
move.w (sp),d0
cmp.w #-1,d0 ; trapping with -1 means return
bne.s check_max ; the corresponding system table
move.l a5,d0
bra.s out
check_max:
cmp.w d5,d0
bcc.s error
add.w d0,d0
add.w d0,d0 ; multiply by 4
move.l 0(a5,d0.w),d0 ; d0 = syscall_tab[d0]
beq.s error ; null entry means invalid call
addq.w #2,sp ; pop function number off stack
move.l d0,a0
jsr (a0) ; go do the call
out:
move.l _curproc,a0